package com.sheep.mybatis.plus.service.impl;
import java.util.Date;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sheep.mybatis.plus.ThreadPoolUtil;
import com.sheep.mybatis.plus.entity.User;
import com.sheep.mybatis.plus.mapper.UserMapper;
import com.sheep.mybatis.plus.service.UserService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


/**
 * Usage                : 用户服务impl
 * Project name         :
 * Author               : lizy4
 * Mail                 : 760470497@qq.com
 * Date                 : 2021/01/14
 * Version              : 1.0.0
 * Modification history :
 * Date          Author          Version          Description
 * ---------------------------------------------------------------
 * 2021/01/14       lizy4             1.0.0             新建
 *
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Override
    @Transactional
    public void mytest() throws InterruptedException {
        System.out.println("开始执行主线程逻辑...");
        User user = new User();
        user.setName("测试");
        user.setPassword("1222");
        user.setSalt("123");
        user.setEmail("345235");
        user.setPhoneNumber("324525");
        user.setStatus(0);
        user.setCreateTime(new Date());
        user.setLastLoginTime(new Date());
        user.setLastUpdateTime(new Date());
        super.save(user);

        // 错误一：另起线程相当于，另外开启了一个事务，一旦发生异常不会回滚主线程的事务
        ThreadPoolUtil.execute(()->{
            // 错误二：该方法中再次对user表进行了操作（不同事务操作同一张表，极易造成锁表）
            this.mytest1(user);
        });

        // 模拟主线程剩下的操作（请求三方接口，http连接保持一分钟）
        // 错误三：结合错误二来看，主线程长时间不提交事务，子线程也不能提交事务，最后会造成数据库被锁
        Thread.sleep(60000);
        System.out.println("主线程逻辑执行完毕...");
    }

    @Override
    @Transactional
    public void mytest1(User user){
        // 一系列操作复杂逻辑操作
        System.out.println("开始执行子线程逻辑...");
        user.setName("测试2");
        super.updateById(user);
        if (1==1){
            throw new RuntimeException("更新操作出错");
        }
        System.out.println("开始执行子线程执行完成...");
    }
}
